package services

import (
	"fmt"
	"gitee.com/captials-team/ubdframe/src/common"
	"gitee.com/captials-team/ubdframe/src/common/utils"
	"gitee.com/captials-team/ubdframe/src/domain/dto"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"gitee.com/captials-team/ubdframe/src/resource"
	"go.uber.org/dig"
	"strings"
)

type RegionInfo struct {
	Data      dto.RegionItem
	Districts []dto.RegionItem
}

// DistrictRegionService 行政区域service
type DistrictRegionService struct {
	l       v1log.ILog
	regions []dto.RegionItem

	regionCache map[string]*RegionInfo
}

func NewDistrictRegionService(di *dig.Container, l v1log.ILog) *DistrictRegionService {
	ctr := &DistrictRegionService{
		l: l,
	}

	ctr.loadDistricts()

	return ctr
}

func (s *DistrictRegionService) loadDistricts() {
	var regions []dto.RegionItem
	var regionCache = make(map[string]*RegionInfo)
	regionCache[""] = &RegionInfo{} //顶级区域节点

	err := utils.ScanEmbedFsDo(resource.RegionsFs, func(file string, path string) error {
		content, err := resource.RegionsFs.ReadFile(path)
		if err != nil {
			return err
		}

		arr := strings.Split(string(content), "\n")

		for _, v := range arr {
			d := dto.DecodeRegionItem(v)

			regions = append(regions, d)
			regionCache[d.Code] = &RegionInfo{
				Data: d,
			}
		}

		return nil
	})
	common.ErrPanic(err)

	for _, v := range regions {
		if _, exist := regionCache[v.ParentCode]; exist {
			d := regionCache[v.ParentCode]
			d.Districts = append(d.Districts, v)
		}
	}

	s.regions = regions
	s.regionCache = regionCache
}

func (s *DistrictRegionService) Query(code string) (dto.RegionItem, error) {
	d, exist := s.regionCache[code]
	if exist {
		return d.Data, nil
	}

	return dto.RegionItem{}, fmt.Errorf("region not exist")
}

func (s *DistrictRegionService) Districts(parentCode string) ([]dto.RegionItem, error) {
	d, exist := s.regionCache[parentCode]
	if exist {
		return d.Districts, nil
	}

	return []dto.RegionItem{}, fmt.Errorf("region not exist")
}
